/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package serv;

import aima.search.framework.SuccessorFunction;
import serv.Estado;
import serv.Servi;
import aima.search.framework.Successor;
import aima.util.Pair;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
/**
 *
 * @author ferran
 */
public class mediumAllSuccessorFunction implements SuccessorFunction{

    @Override
    public List getSuccessors(Object o) {
        Estado state = (Estado) o;
        ArrayList llistaEstatsPosibles = new ArrayList(); 
		
        //guardem lultim estat expandit
		//System.out.println("\n\n_____________________________________________");
        //System.out.println("Estat visitat: ");
        //System.out.println(state.toString());
		//System.out.println("\n_____________________________________________\n\n");
        Servi.lastState = state;
        
        //creo random perque amb el simulatedaneling busqui en random
        
        
        
        
        //iteracions sobre el vector de pairs(usr, fitx) amb les operacions definides
        //recorrem tot el vector de servidors
        for(int i = 0; i < state.fitxers.size(); ++i){
            
            //per cada servidor recorrem tots els pairs
            for(int j = 0; j < state.fitxers.get(i).size(); ++j) { 
                Pair fitx1;
                int serv1 = i, fitxer1;
                fitx1 = state.fitxers.get(i).get(j);
                fitxer1 = (Integer)fitx1.getSecond();
                //per cada pair el canviem per tots els pairs possibles
                for(int k = i + 1; k < state.fitxers.size(); ++k) {
                    
                        for (int q = 0; q < state.fitxers.get(k).size(); ++q){
                            Pair fitx2;
                            int serv2 = k, fitxer2;
                            boolean swapable;
                            fitx2 = state.fitxers.get(k).get(q);
                            fitxer2 = (Integer) fitx2.getSecond();
							
                            swapable = OperacionsSimples.checkSwap(state, serv1, fitx1, serv2, fitx2);
                            if( swapable ){
								//System.out.println("SWAP: serv1: " + serv1 + " \t\t| fitx1: " + fitx1.toString() + " \t\t| serv2: " + serv2 + " \t\t| fitx2: " + fitx2.toString());
								Estado newState = OperacionsSimples.swap(state, serv1, fitx1, serv2, fitx2);
								newState.calculateTempsDescarga();
                                llistaEstatsPosibles.add(new Successor("", newState));
                            }
                        }
					
                }
            }
        }
		

        //iteracio moure
        for(int i = 0; i <state.fitxers.size();++i){
            //iterem per tots els pairs del vector de servidors
            for(int j = 0; j < state.fitxers.get(i).size();++j){
                Pair fitx1;
                int serv1, serv2;
                fitx1 = state.fitxers.get(i).get(j);
                serv1 = i;
                int fitxer1 = (Integer) fitx1.getSecond();
                
                //recorrem el vector de servidors per moure el pair
                for(int k = 0; k < state.fitxers.size(); ++k){
                    serv2 = k;
                    boolean movible;
                    if(i != k){
						movible = OperacionsSimples.checkMove(fitxer1, serv2);
                        if ( movible ){
							//System.out.println("MOVE: serv1: " + serv1 + " \t\t| fitx1: " + fitx1.toString() + " \t\t| serv2: " + serv2);
                            Estado newState = OperacionsSimples.move(state, fitx1, serv1, serv2);
							newState.calculateTempsDescarga();
                            llistaEstatsPosibles.add(new Successor("", newState));
                        }
                    } 
                }
            }
        }
        
        //iterem per treure
        for( int i = 0 ; i < state.fitxers.size() ; ++i ){
            for(int j = 0; j < state.fitxers.get(i).size(); ++j){
                Pair fitx1 = state.fitxers.get(i).get(j);
                
				//System.out.println("TREURE: serv1: " + i  + " \t\t| fitx1: " + fitx1.toString());
                Estado newState = OperacionsMid.treure(state,fitx1, i); 
				newState.calculateTempsDescarga();
                llistaEstatsPosibles.add(new Successor("", newState));
            }
        }
        
        //iterem per posar: fer
		for ( int k = 0 ; k < state.trets.size() ; k++ ) {
			
			for( int i = 0; i < state.fitxers.size(); ++i ){
				boolean posable = OperacionsMid.checkPush(state.trets.get(k), i);
				if ( posable ) {
					//System.out.println("POSAR: serv1: " + i  + " \t\t| fitx1: " + state.trets.get(k).toString());
					Estado newState = OperacionsMid.push(state, k, i);
					newState.calculateTempsDescarga();
					llistaEstatsPosibles.add(new Successor("", newState));
				}
			}
			
		}
        
        //el sampe aki fa lo dels nodes pero no crec k a nosaltres ens calgui, almenys de moment
        return llistaEstatsPosibles;
    }
	
}
